/*
 * Powered By dico
 * Since 2017 - 2018
 */package com.seeyoui.kensite.framework.oa.applyActivity.service;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.seeyoui.kensite.common.base.service.BaseService;
import com.seeyoui.kensite.common.exception.CRUDException;
import com.seeyoui.kensite.common.util.Collections3;
import com.seeyoui.kensite.common.util.StringUtils;
import com.seeyoui.kensite.framework.oa.applyActivity.domain.ApplyActivity;
import com.seeyoui.kensite.framework.oa.applyActivity.persistence.ApplyActivityMapper;
import com.seeyoui.kensite.framework.system.domain.SysDepartment;
import com.seeyoui.kensite.framework.system.domain.SysUser;
import com.seeyoui.kensite.framework.system.service.SysDepartmentService;
import com.seeyoui.kensite.framework.system.service.SysUserService;

/**
 * ApplyActivity
 * @author dico
 * @version 2.0
 * @since 1.0
 * @date 2018-01-05
 */

@Service
public class ApplyActivityService extends BaseService {
	
	@Autowired
	private ApplyActivityMapper applyActivityMapper;
	@Autowired
	private RuntimeService runtimeService;
	@Autowired
	protected TaskService taskService;
	@Autowired
	protected HistoryService historyService;
	@Autowired
	private IdentityService identityService;
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private SysDepartmentService sysDepartMentService;

	/**
	 * 根据ID查询单条数据
	 * @param id
	 * @return
	 * @throws CRUDException
	 */
	public ApplyActivity findOne(String id) throws CRUDException {
		return applyActivityMapper.findOne(id);
	}
	
	/**
	 * 查询审批通过未开始的活动清单
	 * @return
	 */
	public List<ApplyActivity> listPassNotStart() {
		return applyActivityMapper.listPassNotStart();
	}
	
	/**
	 * 根据参数查询最近一次三会一课或党员活动
	 * @param type
	 * @return
	 */
	public ApplyActivity findLastActivity(Integer type) {
		if (type == 1) {
			return applyActivityMapper.findMeeting();
		} else {
			return applyActivityMapper.findActivity();
		}
	}
	
	/**
	 * 三会一课、党员活动更多接口
	 * 近期、往期
	 * @param type
	 * @param state
	 * @return
	 */
	public List<ApplyActivity> listTypeAndState(Integer type, Integer state) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("type", type);
		map.put("state", state);
		return applyActivityMapper.listTypeAndState(map);
	}
	
	/**
	 * 查询数据集合
	 * @param applyActivity
	 * @return
	 * @throws CRUDException
	 */
	public List<ApplyActivity> findList(ApplyActivity applyActivity)
			throws CRUDException {
		return applyActivityMapper.findList(applyActivity);
	}
	
	/**
	 * 查询所有数据集合
	 * @param applyActivity
	 * @return
	 * @throws CRUDException
	 */
	public List<ApplyActivity> findAll(ApplyActivity applyActivity)
			throws CRUDException {
		return applyActivityMapper.findAll(applyActivity);
	}
	
	/**
	 * 查询数据总数
	 * @param applyActivity
	 * @return
	 * @throws CRUDException
	 */
	public int findTotal(ApplyActivity applyActivity) throws CRUDException {
		return applyActivityMapper.findTotal(applyActivity);
	}
	
	/**
	 * 查询数据总数排除当前数据
	 * @param applyActivity
	 * @return
	 * @throws CRUDException
	 */
	public int findExTotal(ApplyActivity applyActivity) throws CRUDException {
		return applyActivityMapper.findExTotal(applyActivity);
	}
	
	/**
	 * 数据新增
	 * @param applyActivity
	 * @throws CRUDException
	 */
	public void save(ApplyActivity applyActivity) throws CRUDException{
		applyActivity.preInsert();
		applyActivityMapper.save(applyActivity);
	}
	
	/**
	 * 数据修改
	 * @param applyActivity
	 * @throws CRUDException
	 */
	public void update(ApplyActivity applyActivity) throws CRUDException{
		applyActivity.preUpdate();
		applyActivityMapper.update(applyActivity);			
	}
	
	/**
	 * 数据删除
	 * @param listId
	 * @throws CRUDException
	 */
	public void delete(List<String> listId) throws CRUDException {
		applyActivityMapper.delete(listId);
	}
	
	/**
	 * 数据假删除
	 * @param applyActivity
	 * @throws CRUDException
	 */
	public void remove(ApplyActivity applyActivity) throws CRUDException{
		applyActivity.preUpdate();
		applyActivityMapper.remove(applyActivity);			
	}
	
	/* 下面方法为流程申请相关*/
	/**
	 * 获取流程详细及工作流参数
	 * @param id
	 */
	@SuppressWarnings("unchecked")
	public ApplyActivity findApplyActivityById(String id) {
		ApplyActivity applyActivity = applyActivityMapper
				.findApplyActivityById(id);
		Map<String, Object> variables = null;
		HistoricProcessInstance historicProcessInstance = historyService
				.createHistoricProcessInstanceQuery()
				.processInstanceId(applyActivity.getBindId()).singleResult();
		if (historicProcessInstance != null) {
			variables = Collections3.extractToMap(
					historyService.createHistoricVariableInstanceQuery()
							.processInstanceId(historicProcessInstance.getId())
							.list(), "variableName", "value");
		} else {
			variables = runtimeService.getVariables(runtimeService
					.createProcessInstanceQuery()
					.processInstanceId(applyActivity.getBindId()).active()
					.singleResult().getId());
		}
		applyActivity.setVariables(variables);
		Task task = taskService.createTaskQuery()
				.processInstanceId(applyActivity.getBindId()).active()
				.singleResult();
		if (task != null) {
			applyActivity.setTask(task);
			applyActivity.getAct().setTask(task);
		} else {
			HistoricTaskInstance histTask = historyService
					.createHistoricTaskInstanceQuery()
					.processInstanceId(applyActivity.getBindId())
					.orderByHistoricTaskInstanceEndTime().desc().list().get(0);
			applyActivity.getAct().setHistTask(histTask);
		}
		return applyActivity;
	}
	
	/**
	 * 启动流程
	 * @param leave
	 * @param variables
	 */
	public void start(ApplyActivity applyActivity, Map<String, Object> variables) {
		if ("党员活动".equals(applyActivity.getType())) {
			applyActivity.setApplySate("0");
			// 保存业务数据
			if (StringUtils.isBlank(applyActivity.getId())) {
				applyActivity.preInsert();
				applyActivityMapper.saveApplyActivity(applyActivity);
			} else {
				applyActivity.preUpdate();
				applyActivityMapper.updateApplyActivity(applyActivity);
			}
			// 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
			identityService.setAuthenticatedUserId(applyActivity
					.getCurrentUser().getUserName());
			// 启动流程
			String businessKey = applyActivity.getId();
			variables.put("type", "apply");
			variables.put("busId", businessKey);
			ProcessInstance processInstance = runtimeService
					.startProcessInstanceByKey("apply", businessKey, variables);
			// 更新流程实例ID
			applyActivity.setBindId(processInstance.getId());
			applyActivityMapper.updateBindid(applyActivity);

		} else {
			applyActivity.setApplySate("1");
			// 保存业务数据
			if (StringUtils.isBlank(applyActivity.getId())) {
				applyActivity.preInsert();
				applyActivityMapper.saveApplyActivity(applyActivity);
			} else {
				applyActivity.preUpdate();
				applyActivityMapper.updateApplyActivity(applyActivity);
			}
		}
	}
	
	/**
	 * 数据新增或修改
	 * @param leave
	 * @throws CRUDException
	 */
	public void saveOrUpdate(ApplyActivity applyActivity) throws CRUDException{
		// 保存业务数据
		if (StringUtils.isBlank(applyActivity.getId())){
			applyActivity.preInsert();
			applyActivityMapper.saveApplyActivity(applyActivity);
		}else{
			applyActivity.preUpdate();
			applyActivityMapper.updateApplyActivity(applyActivity);
		}
	}
	
	/**
	 * 待办任务列表筛选
	 * 根据当前登录对象的部门id与流程发起人的部分id匹配
	 * 将符合的待办任务返回
	 * @param list
	 * @param sysUser
	 * @return
	 */
	public List<HashMap<String, String>> manageListTodo(
			List<HashMap<String, String>> list, SysUser sysUser) {
		List<HashMap<String, String>> todoList = new ArrayList<HashMap<String, String>>();
		for (HashMap<String, String> hashMap : list) {
			String name = hashMap.get("vars.applyUserId");
			SysUser applyUser = sysUserService.findSysUserByName(name);
			List<String> didList = new ArrayList<String>();
			boolean go = true;
			SysDepartment sysDept = sysDepartMentService.findOne(applyUser
					.getDepartmentId());
			didList.add(sysDept.getId());
			do {
				SysDepartment sysParent = sysDepartMentService.findOne(sysDept
						.getParentId());
				if (sysParent == null) {
					go = false;
				} else {
					didList.add(sysParent.getId());
					sysDept = sysDepartMentService.findOne(sysParent.getId());
				}
			} while (go);

			for (String deptId : didList) {
				if (deptId.equals(sysUser.getDepartmentId())) {
					todoList.add(hashMap);
				}
			}
		}
		return todoList;
	}
	
}